﻿// MedicalRulesEngine.Infrastructure/Data/RulesDbContext.cs
using MedicalRulesEngine.Domain.Entities;
using Microsoft.EntityFrameworkCore;



namespace MedicalRulesEngine.Infrastructure.Data;

/// <summary>
/// 规则引擎数据库上下文
/// 使用Code-First方式管理数据库结构
/// </summary>
public class RulesDbContext : DbContext
{
    public RulesDbContext(DbContextOptions<RulesDbContext> options) : base(options)
    {
    }

    /// <summary>
    /// 元数据规则集合
    /// </summary>
    public DbSet<MetadataRule> MetadataRules { get; set; }

    /// <summary>
    /// 规则条件集合
    /// </summary>
    public DbSet<RuleCondition> RuleConditions { get; set; }

    /// <summary>
    /// 规则动作集合
    /// </summary>
    public DbSet<RuleAction> RuleActions { get; set; }

    /// <summary>
    /// 规则标签集合
    /// </summary>
    public DbSet<RuleTag> RuleTags { get; set; }

    /// <summary>
    /// 规则执行日志集合
    /// </summary>
    public DbSet<RuleExecutionLog> RuleExecutionLogs { get; set; }

    /// <summary>
    /// 字段定义集合
    /// </summary>
    public DbSet<FieldDefinition> FieldDefinitions { get; set; }

    /// <summary>
    /// 操作符定义集合
    /// </summary>
    public DbSet<OperatorDefinition> OperatorDefinitions { get; set; }

    /// <summary>
    /// 规则模板集合
    /// </summary>
    public DbSet<RuleTemplate> RuleTemplates { get; set; }

    /// <summary>
    /// 配置实体关系和约束
    /// </summary>
    /// <param name="modelBuilder">模型构建器</param>
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // 配置MetadataRule实体
        modelBuilder.Entity<MetadataRule>(entity =>
        {
            entity.ToTable("MetadataRules");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.Name).IsRequired().HasMaxLength(200);
            entity.Property(e => e.Code).IsRequired().HasMaxLength(50);
            entity.Property(e => e.WorkflowName).IsRequired().HasMaxLength(100);
            entity.Property(e => e.Category).IsRequired().HasMaxLength(50);
            entity.Property(e => e.Priority).HasConversion<int>();
            entity.Property(e => e.Status).HasConversion<int>();
            entity.HasIndex(e => e.Code).IsUnique();
            entity.HasIndex(e => new { e.WorkflowName, e.Category });
        });

        // 配置RuleCondition实体
        modelBuilder.Entity<RuleCondition>(entity =>
        {
            entity.ToTable("RuleConditions");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.FieldPath).IsRequired().HasMaxLength(200);
            entity.Property(e => e.Operator).IsRequired().HasMaxLength(50);
            entity.Property(e => e.LogicalOperator).HasMaxLength(10).HasDefaultValue("AND");

            // 配置与MetadataRule的关系
            entity.HasOne(e => e.Rule)
                  .WithMany(r => r.Conditions)
                  .HasForeignKey(e => e.RuleId)
                  .OnDelete(DeleteBehavior.Cascade);

            // 配置自引用关系（父子条件）
            entity.HasOne(e => e.ParentCondition)
                  .WithMany(c => c.ChildConditions)
                  .HasForeignKey(e => e.ParentConditionId)
                  .OnDelete(DeleteBehavior.Restrict);
        });

        // 配置RuleAction实体
        modelBuilder.Entity<RuleAction>(entity =>
        {
            entity.ToTable("RuleActions");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.Name).IsRequired().HasMaxLength(100);
            entity.Property(e => e.ActionType).IsRequired().HasMaxLength(50);

            // 配置与MetadataRule的关系
            entity.HasOne(e => e.Rule)
                  .WithMany(r => r.Actions)
                  .HasForeignKey(e => e.RuleId)
                  .OnDelete(DeleteBehavior.Cascade);
        });

        // 配置RuleTag实体
        modelBuilder.Entity<RuleTag>(entity =>
        {
            entity.ToTable("RuleTags");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.Name).IsRequired().HasMaxLength(50);
            entity.Property(e => e.Value).HasMaxLength(100);
            entity.Property(e => e.Color).HasMaxLength(20);

            // 配置与MetadataRule的关系
            entity.HasOne(e => e.Rule)
                  .WithMany(r => r.Tags)
                  .HasForeignKey(e => e.RuleId)
                  .OnDelete(DeleteBehavior.Cascade);
        });

        // 配置RuleExecutionLog实体
        modelBuilder.Entity<RuleExecutionLog>(entity =>
        {
            entity.ToTable("RuleExecutionLogs");
            entity.HasKey(e => e.Id);
            entity.HasIndex(e => e.ExecutedAt);
            entity.HasIndex(e => new { e.RuleId, e.ExecutedAt });

            // 配置与MetadataRule的关系
            entity.HasOne(e => e.Rule)
                  .WithMany(r => r.ExecutionLogs)
                  .HasForeignKey(e => e.RuleId)
                  .OnDelete(DeleteBehavior.Cascade);
        });

        // 配置FieldDefinition实体
        modelBuilder.Entity<FieldDefinition>(entity =>
        {
            entity.ToTable("FieldDefinitions");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.Name).IsRequired().HasMaxLength(100);
            entity.Property(e => e.Path).IsRequired().HasMaxLength(200);
            entity.Property(e => e.DisplayName).IsRequired().HasMaxLength(100);
            entity.Property(e => e.DataType).IsRequired().HasMaxLength(50);
            entity.Property(e => e.Category).IsRequired().HasMaxLength(50);
            entity.HasIndex(e => e.Path).IsUnique();
            entity.HasIndex(e => new { e.Category, e.Order });
        });

        // 配置OperatorDefinition实体
        modelBuilder.Entity<OperatorDefinition>(entity =>
        {
            entity.ToTable("OperatorDefinitions");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.Code).IsRequired().HasMaxLength(50);
            entity.Property(e => e.DisplayName).IsRequired().HasMaxLength(100);
            entity.HasIndex(e => e.Code).IsUnique();
        });

        // 配置RuleTemplate实体
        modelBuilder.Entity<RuleTemplate>(entity =>
        {
            entity.ToTable("RuleTemplates");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.Name).IsRequired().HasMaxLength(200);
            entity.Property(e => e.Code).IsRequired().HasMaxLength(50);
            entity.Property(e => e.Category).IsRequired().HasMaxLength(50);
            entity.HasIndex(e => e.Code).IsUnique();
            entity.HasIndex(e => new { e.Category, e.Order });
        });
    }
}

